home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / µSim 1.0.5 / source / Simulator.c < prev    next >
Encoding:
Text File  |  1995-11-01  |  11.6 KB  |  436 lines  |  [TEXT/CWIE]

  1. /*
  2. Copyright © 1993,1994,1995 Fabrizio Oddone
  3. ••• ••• ••• ••• ••• ••• ••• ••• ••• •••
  4. This source code is distributed as freeware:
  5. you may copy, exchange, modify this code.
  6. You may include this code in any kind of application: freeware,
  7. shareware, or commercial, provided that full credits are given.
  8. You may not sell or distribute this code for profit.
  9. */
  10.  
  11. //#pragma load "MacDump"
  12.  
  13. #pragma fourbyteints on
  14. #include    <stdlib.h>
  15. #pragma fourbyteints reset
  16.  
  17. #include    "UtilsSys7.h"
  18.  
  19. #include    "Globals.h"
  20. #include    "AEHandlers.h"
  21. #include    "Animation.h"
  22. #include    "Compares.h"
  23. #include    "Dump.h"
  24. #include    "Input.h"
  25. #include    "Microprogram_Ed.h"
  26. #include    "Registers.h"
  27. #include    "Simulator.h"
  28. #include    "SimUtils.h"
  29.  
  30. #if defined(FabSystem7orlater)
  31.  
  32. //#pragma segment Main
  33.  
  34. enum conditions {
  35. kCOND_NEVER = 0,
  36. kCOND_N,
  37. kCOND_Z,
  38. kCOND_ALWAYS
  39. };
  40.  
  41. const short reading[] = { kP_MBR, kP_MBRMEM, 0};
  42. const short readstart[] = { kP_MAR2MEM, 0};
  43. const short writestart[] = { kP_MBRMEM, kP_MAR2MEM, 0};
  44.  
  45. static short    Abus, Bbus, Cbus;
  46. static union u_mir mir;
  47.  
  48. static short alu(void);
  49. static void shifter(void);
  50. static Boolean memory(void);
  51. static void ZoomEffectMap2MPC(void);
  52.  
  53. /* MSL: models the Micro Sequencing Logic */
  54. #define MSL()    ((mir.bits.cond == kCOND_ALWAYS) || ((mir.bits.cond == kCOND_Z) && \
  55.                 (gParts[kP_ALU - kFIRST_PICT] == 0)) || ((mir.bits.cond == kCOND_N) \
  56.                 && (gParts[kP_ALU - kFIRST_PICT] < 0)))
  57.  
  58. /* AMUX: models the A multiplexer */
  59. #define    AMUX()    (mir.bits.amux ? gParts[kP_MBR - kFIRST_PICT] : \
  60.                     gParts[kP_ALATCH - kFIRST_PICT])
  61.  
  62. /* MMUX: models the M multiplexer */
  63. #define    MMUX()    ((mslflag = MSL()) ? mir.bits.addr : gParts[kP_INCR - kFIRST_PICT])
  64.  
  65. /* alu: models the Arithmetic Logical Unit */
  66.  
  67. static short alu(void)
  68. {
  69. register short value;
  70.  
  71. value = AMUX();
  72. gParts[kP_AMUX - kFIRST_PICT] = value;
  73. switch(mir.bits.alu) {
  74.     case 1:    value += Bbus;
  75.         break;
  76.     case 2:    value &= Bbus;
  77.         break;
  78.     case 3:    value = ~value;
  79.         break;
  80.     }
  81. gParts[kP_ALU - kFIRST_PICT] = value;
  82. if (gRstatus > kST_STEPASM) {
  83.     ChangedBox(kP_AMUX - kFIRST_PICT);
  84.     ChangedBox(kP_ALU - kFIRST_PICT);
  85.     }
  86. return value;
  87. }
  88.  
  89. /* shifter: models the (!) shifter */
  90.  
  91. static void shifter(void)
  92. {
  93. register short value;
  94.  
  95. value = alu();
  96. switch(mir.bits.shift) {
  97.     case 1: value <<= 1;
  98.         break;
  99.     case 2: value = (unsigned short)value >> 1;
  100.         break;
  101.     case 3: value >>= 1;
  102.     }
  103. gParts[kP_SHIFTER - kFIRST_PICT] = value;
  104. if (gRstatus > kST_STEPASM) {
  105.     ChangedBox(kP_SHIFTER - kFIRST_PICT);
  106.     }
  107. Cbus = value;
  108. }
  109.  
  110. /* MAR: models the Memory Address Register */
  111.  
  112. #define MAR()    \
  113. {    \
  114. if (mir.bits.mar) {    \
  115.     gParts[kP_MAR - kFIRST_PICT] = gParts[kP_BLATCH - kFIRST_PICT];    \
  116.     if (gRstatus > kST_STEPASM) {    \
  117.         ChangedBox(kP_MAR - kFIRST_PICT);    \
  118.         if (gRstatus == kST_STEPSUBCYC)    \
  119.             ActivateObjs(marobjs);    \
  120.         }    \
  121.     }    \
  122. }
  123.  
  124. /* MAR: models the Memory Buffer Register */
  125.  
  126. #define MBR()    \
  127. {    \
  128. if (mir.bits.mbr) {    \
  129.     gParts[kP_MBR - kFIRST_PICT] = Cbus;    \
  130.     if (gRstatus > kST_STEPASM) {    \
  131.         ChangedBox(kP_MBR - kFIRST_PICT);    \
  132.         if (gRstatus == kST_STEPSUBCYC)    \
  133.             ActivateObjs(mbrobjs);    \
  134.         }    \
  135.     }    \
  136. }
  137.  
  138. /* ExecuteInstructions: executes instructions for a clock subcycle,
  139. taking care of the necessary user interface updates */
  140.  
  141. /* da schiaffare dentro la routine successiva */
  142. const short subc0[] = { kP_MPC2INC, kP_INCR, kP_MPC2CST, kP_CST2MIR, kP_REG2LTCH1, kP_REG2LTCH2, 0 };
  143. const short subc1[] = { kP_ALATCH, kP_BLATCH, 0 };
  144. const short shftaluamux[] = { kP_AMUX2ALU, kP_BLTCH2ALU, kP_ALU, kP_ALU2SH, kP_SHIFTER, 0};
  145. const short shftoregs[] = { kP_SH2REGS1, kP_SH2REGS2, kP_SH2REGS3, 0 };
  146. const short marobjs[] = { kP_MAR, kP_BLTCH2MAR1, kP_BLTCH2MAR2, 0 };
  147. const short mbrobjs[] = { kP_MBR, kP_SH2MBR1, kP_SH2MBR2, 0 };
  148. const short mapobjs[] = { kP_MAP, kP_MAPREGS, 0 };
  149. const short fromabus[] = { kP_ALTCH2AMUX, kP_AMUX, 0 };
  150. const short frommbr[] = { kP_MBR2AMUX, kP_AMUX, 0 };
  151. const short fromincr[] = { kP_INC2MMUX1, kP_INC2MMUX2, kP_MMUX, kP_MPC, 0};
  152. const short frommir[] = { kC_ADDR1, kC_ADDR2, kP_MMUX, kP_MPC, 0 };
  153. const short mmux2mpc[] = { kP_MMUX2MPC, 0 };
  154.  
  155. void ExecuteInstructions(short subclock)
  156. {
  157. register Handle    tempH;
  158. register Ptr    base;
  159. static unsigned short    mapLine;
  160. static Boolean    mslflag;
  161.  
  162. switch (subclock) {
  163.     case 0:
  164.         gParts[kP_INCR - kFIRST_PICT] = gParts[kP_MPC - kFIRST_PICT] + 1;
  165.         if (gRstatus > kST_STEPASM) {
  166.             ChangedBox(kP_INCR - kFIRST_PICT);
  167.             if (gRstatus == kST_STEPSUBCYC) {
  168.                 DeactivateObjs(shftoregs);
  169.                 DeactivateObjs(mbrobjs);
  170.                 DeactivateObjs(mapobjs);
  171.                 DeactivateObjs(writestart);
  172.                 if (mslflag)
  173.                     DeactivateObjs(frommir);
  174.                 else
  175.                     DeactivateObjs(fromincr);
  176.                 ActivateObjs(subc0);
  177.                 if (mir.bits.map)
  178.                     SelectLLine(kL_INSTR, mapLine);
  179.                 else {
  180.                     DeactivateObjs(mmux2mpc);
  181.                     SelectLLine(kL_COMMENTS, gParts[kP_MPC - kFIRST_PICT]);
  182.                     }
  183.                 }
  184.             }
  185.         mir = gCsMemory[gParts[kP_MPC - kFIRST_PICT]];
  186.         Abus = gRegs[mir.bits.a];
  187.         Bbus = gRegs[mir.bits.b];
  188.         break;
  189.     case 1:
  190.         gParts[kP_ALATCH - kFIRST_PICT] = Abus;
  191.         gParts[kP_BLATCH - kFIRST_PICT] = Bbus;
  192.         if (gRstatus > kST_STEPASM) {
  193.             ChangedBox(kP_ALATCH - kFIRST_PICT);
  194.             ChangedBox(kP_BLATCH - kFIRST_PICT);
  195.             if (gRstatus == kST_STEPSUBCYC) {
  196.                 DeactivateObjs(subc0);
  197.                 ActivateObjs(subc1);
  198.                 }
  199.             }
  200.         break;
  201.     case 2:
  202.         shifter();
  203.         MAR()
  204.         if (gRstatus == kST_STEPSUBCYC) {
  205.             DeactivateObjs(subc1);
  206.             ActivateObjs(shftaluamux);
  207.             if (mir.bits.amux)
  208.                 ActivateObjs(frommbr);
  209.             else
  210.                 ActivateObjs(fromabus);
  211.             }
  212.         break;
  213.     case 3:
  214.         if (mir.bits.dsc == 0) {
  215.             gRegs[mir.bits.c] = Cbus;
  216.             if (gRstatus > kST_STEPASM) {
  217.                 ChangedRegister(mir.bits.c);
  218.                 if (gRstatus == kST_STEPSUBCYC)
  219.                     ActivateObjs(shftoregs);
  220.                 }
  221.             }
  222.         MBR()
  223.         gParts[kP_MPC - kFIRST_PICT] = gParts[kP_MMUX - kFIRST_PICT] = MMUX();
  224.         (void)memory();
  225.         if (mir.bits.map) {
  226. //#define    Ext12(x)    (((x) << 4) >> 4)
  227. //#define    Ext11(x)    (((x) << 5) >> 5)
  228.             gRegs[kREG_EXT12] = gRegs[kREG_IR] << 4;
  229.             gRegs[kREG_EXT12] >>= 4;
  230.             gRegs[kREG_EXT11] = gRegs[kREG_IR] << 5;
  231.             gRegs[kREG_EXT11] >>= 5;
  232.             gRegs[kREG_LOW8] = gRegs[kREG_IR] & 0x00FF;
  233.             gParts[kP_MPC - kFIRST_PICT] = *(gAssMemory + *(Byte *)&gRegs[kREG_IR]);
  234.             if (gRstatus > kST_STEPASM) {
  235.                 ChangedRegister(kREG_EXT12);
  236.                 ChangedRegister(kREG_EXT11);
  237.                 ChangedRegister(kREG_LOW8);
  238.                 tempH = Get1Resource(krInstructions, kOPCODES);
  239.                 base = StripAddress(&((ROpcodePtr)*tempH)->offsetHB) + 2;
  240.                 mapLine = (unsigned)(StripAddress(bsearch(&gRegs[kREG_IR], base,
  241.                     *(unsigned short *)*tempH + 1, sizeof(ROpcode), compareOpc))
  242.                     - base) / (unsigned short)sizeof(ROpcode);
  243.                 ZoomEffectMap2MPC();
  244.                 if (gRstatus == kST_STEPSUBCYC)
  245.                     ActivateObjs(mapobjs);
  246.                 else
  247.                     SelectLLine(kL_INSTR, mapLine);
  248.                 }
  249.             }
  250.         if (gRstatus > kST_STEPASM) {
  251.             ChangedBox(kP_MMUX - kFIRST_PICT);
  252.             ChangedBox(kP_MPC - kFIRST_PICT);
  253.             if (gRstatus == kST_STEPSUBCYC) {
  254.                 DeactivateObjs(shftaluamux);
  255.                 DeactivateObjs(marobjs);
  256.                 if (mir.bits.amux)
  257.                     DeactivateObjs(frommbr);
  258.                 else
  259.                     DeactivateObjs(fromabus);
  260.                 if (mslflag)
  261.                     ActivateObjs(frommir);
  262.                 else
  263.                     ActivateObjs(fromincr);
  264.                 if (mir.bits.map == 0)
  265.                     ActivateObjs(mmux2mpc);
  266.                 }
  267.             else
  268.                 SelectLLine(kL_COMMENTS, gParts[kP_MPC - kFIRST_PICT]);
  269.             }
  270.         break;
  271.     }
  272. }
  273.  
  274. /* memory: models the external RAM memory */
  275.  
  276. static Boolean memory(void)
  277. {
  278. register short *tempP;
  279. register unsigned short    firstWordinWind;
  280. static Boolean rdInitiated = false, wrInitiated = false;
  281. register Boolean    stoppedForIO = false;
  282.  
  283. if (mir.bits.rd) {
  284.     if (rdInitiated) {
  285.         tempP = ((short *)gMMemory + (unsigned short)gParts[kP_MAR - kFIRST_PICT]);
  286.         gParts[kP_MBR - kFIRST_PICT] = *tempP;
  287.         if (gRstatus > kST_STEPASM) {
  288.             ChangedBox(kP_MBR - kFIRST_PICT);
  289.             if (gRstatus == kST_STEPSUBCYC)
  290.                 ActivateObjs(reading);
  291.             }
  292.         /* handle memory mapped input */
  293.         if ((Ptr)tempP == (gMMemory + kSIZE_RAM - 4)) {
  294.             if ((gInTheForeground == false)||(gWPtr_IO != FrontWindow())) {
  295.                 SendmyAE(kFCR_MINE, kAEmySignalIO, myIdleFunct, kAENoReply | kAEAlwaysInteract | kAECanSwitchLayer);
  296.                 stoppedForIO = true;
  297.                 }
  298.             }
  299.         rdInitiated = false;
  300.         }
  301.     else {
  302.         rdInitiated = true;
  303.         if (gRstatus == kST_STEPSUBCYC)
  304.             ActivateObjs(readstart);
  305.         }
  306.     }
  307. if (mir.bits.wr) {
  308.     if (wrInitiated) {
  309.         tempP = ((short *)gMMemory + (unsigned short)gParts[kP_MAR - kFIRST_PICT]);
  310.         *tempP = gParts[kP_MBR - kFIRST_PICT];
  311.         wrInitiated = false;
  312.         /* update Dump Window only if necessary */
  313.         if (EmptyRgn(gWPtr_Dump->visRgn) == false)
  314.             if ((firstWordinWind = (unsigned short)GetControlValue(dumpVScroll) << 4)
  315.                                 <= (unsigned short)gParts[kP_MAR - kFIRST_PICT])
  316.                 if (((firstWordinWind - 1) + 
  317.                         ((PRCT_B(gWPtr_Dump) - PRCT_T(gWPtr_Dump)) / dumpLineHeight) << 3)
  318.                         >= (unsigned short)gParts[kP_MAR - kFIRST_PICT])
  319.                     InvalDump();
  320.         /* handle memory mapped output */
  321.         if ((Ptr)tempP == (gMMemory + kSIZE_RAM - 2)) {
  322.             DoKeyDown(gWPtr_IO, ((unsigned char *)tempP)[1], false);
  323.             if ((gInTheForeground == false)||(gWPtr_IO != FrontWindow()))
  324.                 SendmyAE(kFCR_MINE, kAEmySignalIO, myIdleFunct, kAENoReply | kAEAlwaysInteract | kAECanSwitchLayer);
  325.             *tempP = 0;
  326.             }
  327.         }
  328.     else {
  329.         wrInitiated = true;
  330.         if (gRstatus == kST_STEPSUBCYC)
  331.             ActivateObjs(writestart);
  332.         }
  333.     }
  334. return stoppedForIO;
  335. }
  336.  
  337. /* ExecuteInstructionsGO: executes a conventional instruction of the
  338. simulated program, updating only the Dump window */
  339.  
  340. void ExecuteInstructionsGO(void)
  341. {
  342. enum {
  343. kMAX_COMPUTE = 120L
  344. };
  345.  
  346. register unsigned long    tickc;
  347. register unsigned long    interval;
  348. register short value;
  349. register Boolean    mslflag, hasPaused;
  350.  
  351. tickc = TickCount();
  352. do {
  353.     gParts[kP_INCR - kFIRST_PICT] = gParts[kP_MPC - kFIRST_PICT] + 1;
  354.     mir = gCsMemory[gParts[kP_MPC - kFIRST_PICT]];
  355.     gParts[kP_ALATCH - kFIRST_PICT] = gRegs[mir.bits.a];
  356.     gParts[kP_BLATCH - kFIRST_PICT] = gRegs[mir.bits.b];
  357.     value = AMUX();
  358.     gParts[kP_AMUX - kFIRST_PICT] = value;
  359.     switch(mir.bits.alu) {
  360.         case 1:    value += gParts[kP_BLATCH - kFIRST_PICT];
  361.             break;
  362.         case 2:    value &= gParts[kP_BLATCH - kFIRST_PICT];
  363.             break;
  364.         case 3:    value = ~value;
  365.             break;
  366.         }
  367.     gParts[kP_ALU - kFIRST_PICT] = value;
  368.     switch(mir.bits.shift) {
  369.         case 1: value <<= 1;
  370.             break;
  371.         case 2: value = (unsigned short)value >> 1;
  372.             break;
  373.         case 3: value >>= 1;
  374.         }
  375.     gParts[kP_SHIFTER - kFIRST_PICT] = value;
  376.     if (mir.bits.mar)
  377.         gParts[kP_MAR - kFIRST_PICT] = gParts[kP_BLATCH - kFIRST_PICT];
  378.     if (mir.bits.dsc == 0)
  379.         gRegs[mir.bits.c] = value;
  380.     if (mir.bits.mbr)
  381.         gParts[kP_MBR - kFIRST_PICT] = value;
  382.     gParts[kP_MPC - kFIRST_PICT] = gParts[kP_MMUX - kFIRST_PICT] = MMUX();
  383.     hasPaused = memory();
  384.     if (mir.bits.map) {
  385.         gRegs[kREG_EXT12] = gRegs[kREG_IR] << 4;
  386.         gRegs[kREG_EXT12] >>= 4;
  387.         gRegs[kREG_EXT11] = gRegs[kREG_IR] << 5;
  388.         gRegs[kREG_EXT11] >>= 5;
  389.         gRegs[kREG_LOW8] = gRegs[kREG_IR] & 0x00FF;
  390.         gParts[kP_MPC - kFIRST_PICT] = *(gAssMemory + *(Byte *)&gRegs[kREG_IR]);
  391.         }
  392.     interval = TickCount() - tickc;
  393.     }
  394. while ((gParts[kP_MPC - kFIRST_PICT]) && (interval < kMAX_COMPUTE));
  395. if (gPrefs.infLoopsDetect && (hasPaused == false) && (interval >= kMAX_COMPUTE) && gParts[kP_MPC - kFIRST_PICT]) {
  396.     (void)StopAlert_AE(kALRT_INFLOOP, myStdFilterProcNoCancel, myIdleFunct);
  397.     StopIt();
  398.     }
  399. }
  400.  
  401. /* ZoomEffectMap2MPC: the hardware decoding unit is modifying
  402. the Micro Program Counter; let the user have a visual feedback */
  403.  
  404. static void ZoomEffectMap2MPC(void)
  405. {
  406. GrafPtr    savePort;
  407. Rect    mapRect, mpcRect;
  408. register PicHandle    tempPH;
  409.  
  410. GetPort(&savePort);
  411. SetPort(gWPtr_Animation);
  412. tempPH = images[kP_MAP - kFIRST_PICT];
  413. if (*tempPH == nil)
  414.     LoadResource((Handle)tempPH);
  415. mapRect = (*tempPH)->picFrame;
  416. tempPH = images[kP_MPC - kFIRST_PICT];
  417. if (*tempPH == nil)
  418.     LoadResource((Handle)tempPH);
  419. mpcRect = (*tempPH)->picFrame;
  420. /* zoomFactor: 5 good on a Plus, 8 on a Quadra 700 */
  421. ZoomRectToRect(&mapRect, &mpcRect, gZoomFactor);
  422. SetPort(savePort);
  423. }
  424.  
  425. /* StopIt: stops the processing */
  426.  
  427. void StopIt(void)
  428. {
  429. gRstatus = kST_STOPPED;
  430. ChangedAllRegisters();
  431. ChangedAllBoxes();
  432. }
  433.  
  434. #endif
  435.  
  436.